package com.ocl.www.controller;

import java.io.UnsupportedEncodingException;
import java.sql.Timestamp;
import java.util.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.sound.sampled.AudioFormat.Encoding;

import com.ocl.www.domain.*;
import com.ocl.www.service.ArticleImageService;
import com.ocl.www.service.ArticleService;
import com.ocl.www.service.UserAttentionService;
import com.ocl.www.utils.UserUntil;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections.map.HashedMap;
import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.crypto.hash.Sha512Hash;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.noggit.JSONUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import com.ocl.www.basic.BasicController;
import com.ocl.www.security.ShiroCasConfiguration;
import com.ocl.www.service.UserService;
import com.ocl.www.utils.Digests;
import com.ocl.www.utils.ResourceBundleUtils;

import static org.apache.shiro.web.filter.mgt.DefaultFilter.user;

@RestController
@RequestMapping("/user")
public class UserController extends BasicController {
	
	@Autowired
	private UserService userService;
	@Autowired
	private ArticleService articleService;
	@Autowired
	private UserAttentionService userAttentionService;
	@Autowired
	private ArticleImageController articleImageController;
	@Autowired
	private ArticleImageService articleImageService;
	@Autowired
	private EhCacheManager em;


	private Logger log = Logger.getLogger(UserController.class);


	/**
	 * 得到一个用户和该用户的文章
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "/getUserWithArticle", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
	@ApiOperation(value="得到一个用户和该用户的文章，粉丝，文章", notes="得到一个用户和该用户的文章，粉丝，文章")
	@ApiImplicitParam(name = "map", value = "使用此格式：{}", required = true, dataType = "Map")
	public Map<String,Object> getUserWithArticle(@RequestBody Map<String,Object> map, HttpSession httpSession){
		log.info(httpSession.getId());
		httpSession.setAttribute("myname","guoxiaolin");
		Map<String,Object> map1 = new HashedMap();

//		Set<?> s = SecurityUtils.getSubject().getPrincipals().asSet();

		List<Article> articlelist = (List<Article>) em.getCache("shiroCache").get("hotArticle");
		int userid =  0;
		try {
			userid = articlelist.get((Integer) map.get("index")).getAuthor();
		}catch (IndexOutOfBoundsException e){
			map1.put("info","0");
			map1.put("tip","无更多数据");
			return map1;

		}



		try {
			User user = new User();
			user.setUserId(userid);
			map1.put("info","1");
			map1.put("user",userService.findUserInfo(user));
		} catch (Exception e) {
			//e.printStackTrace();
			map1.put("info","0");
			map1.put("tip","用户查询失败："+e.getMessage());
			return map1;
		}

		try {
			UserFans userFans = new UserFans();
			userFans.setUserId(userid);
			map1.put("userfanslist",userService.getFans(userFans));
		} catch (Exception e) {
			//e.printStackTrace();
			map1.put("info","0");
			map1.put("tip","用户粉丝查询失败："+e.getMessage());
			return map1;
		}

		try {
			Article article = new Article();
			article.setAuthor(userid);
			map1.put("articleList",articleService.selectArticles(article));
		} catch (Exception e) {
			//e.printStackTrace();
			map1.put("info","0");
			map1.put("tip","用户文章查询失败："+e.getMessage());
			return map1;
		}

		return map1;
	}

	/**
	 *
	 * @Title: UserController
	 * @Description: 获取用户信息
	 * @param: @param user
	 * @param: @return
	 * @return: User
	 * @throws
	 */
	@ResponseBody
	@RequestMapping(value = "/getUserInfo2", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
	@ApiOperation(value="得到一个用户和该用户的文章，标签，文章", notes="得到一个用户和该用户的文章，标签，文章")
	@ApiImplicitParam(name = "maptemp", value = "使用此格式：{}", required = true, dataType = "Map")
	public Map<String,Object> getUserInfo2 (@RequestBody Map<String,Object> maptemp) {

		User user = new User();
		Map<String,Object> map = new HashedMap();
//		log.info((int)em.getCache("shiroCache").get("user_id"));

		user.setUserId(Integer.valueOf(maptemp.get("userId").toString()));
		//user.setPassword("123123");

		try {

			user = userService.findUserInfo(user);

			List<UserAttention> userAttentionList =userAttentionService.queryAttentionOfUser(user.getUserId());

			String tags = "";
			for (int i =0 ;i<userAttentionList.size();i++){
				if (i==userAttentionList.size()-1){
					tags = tags + userAttentionList.get(i).getCategoryName();
				}else{
					tags = tags + userAttentionList.get(i).getCategoryName()+",";
				}

			}
			Article art = new Article();
			art.setAuthor(user.getUserId());
			List<Article> articlelist = articleService.selectArticles(art);

			map.put("user",user);
			map.put("usertags",tags);
			map.put("articlelist",articlelist);

		} catch (Exception e) {
			e.printStackTrace();
		}
		log.info("查询成功...map of user"+map.toString());
		return map;
	}
	/**
	 *
	 * @Title: UserController
	 * @Description: 获取文章及其对应的用户信息及图片
	 * @param: @param user
	 * @param: @return
	 * @return: map
	 * @throws
	 */
	@ResponseBody
	@RequestMapping(value = "/getUserAndArticle", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
	@ApiOperation(value="获取文章及其对应的用户信息及图片", notes="获取文章及其对应的用户信息及图片")
	@ApiImplicitParam(name = "mapinfo", value = "使用此格式：{}", required = true, dataType = "Map")
	public Map getUserAndArticle (@RequestBody Map<String,Object> mapinfo) {
		Map<String,Object> map = new HashMap();


		User user = new User();
		log.info("文章的用户id："+mapinfo.get("author"));
		Integer tempid =Integer.valueOf(String.valueOf(mapinfo.get("author")));
		user.setUserId(tempid);
		try {
			user = userService.findUserInfo(user);
			map.put("user",user);
		} catch (Exception e) {
			e.printStackTrace();
		}

		Article article = new Article();
		tempid = Integer.valueOf(String.valueOf(mapinfo.get("articleId")));
		article.setArticleId(tempid);
		log.info("文章的id："+article.getArticleId());
		try {
			article = articleService.selectArticle(article);

			map.put("article",article);
		} catch (Exception e) {
			e.printStackTrace();
		}

//		List<Article> articlelist = new ArrayList<Article>();
//		tempid = Integer.valueOf(String.valueOf(mapinfo.get("author")));
//		Article articles = new Article();
//		articles.setAuthor(tempid);
//		log.info("文章的id："+article.getArticleId());
//		try {
//			articlelist = articleService.selectArticles(articles);
//			map.put("articlelist",articlelist);
//		} catch (Exception e) {
//			e.printStackTrace();
//		}

		try {
			ArticleImages articleImages = new ArticleImages();
			articleImages.setDetailId(article.getArticleId());
			map.put("articleimagelist",articleImageService.getImagesOfArticle(articleImages));
		} catch (Exception e) {
			e.printStackTrace();
		}



		return map;
	}
	/**
	 * 
	 * @Title: UserController
	 * @Description: 进入个人首页
	 * @param: @param user
	 * @param: @return
	 * @return: User
	 * @throws
	 */
	@ApiOperation(value="进入个人首页", notes="进入个人首页(get方式)")
	@RequestMapping(value = "/personIndex", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
	public ModelAndView personIndex (User User) {
		
		ModelAndView mav = new ModelAndView();
		mav.setViewName("redirect:"+ResourceBundleUtils.getProperty("project.page.host")+"/person.html");
		
		return mav;
	}
	
	/**
	 * 
	 * @Title: UserController
	 * @Description: 进入个人信息编辑页面
	 * @return: User
	 * @throws
	 */

	@ApiOperation(value="进入个人信息编辑页面", notes="进入个人信息编辑页面(get方式)")
	@RequestMapping(value = "/editInfo", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
	public ModelAndView editInfo () {
		
		ModelAndView mav = new ModelAndView();
		mav.setViewName("redirect:"+ResourceBundleUtils.getProperty("project.page.host")+"/setting.html");
		
		return mav;
	}
	
	
	/**
	 * 
	 * @Title: UserController
	 * @Description: 修改用户密码信息
	 * @param: @param user
	 * @param: @return
	 * @return: User
	 * @throws
	 */
	@ResponseBody
	@RequestMapping(value = "/updatepassword", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
	@ApiOperation(value="修改用户密码信息", notes="修改用户密码信息(post方式，已过时)")
	@ApiImplicitParam(name = "maptemp", value = "使用此格式：{}", required = true, dataType = "Map")
	public int updatepassword (@RequestBody  Map<String,String> map) {
		String currentpassword = map.get("currentpassword");
		String newpassword = map.get("newpassword");
		//User user = new User();
		
//		int userid = (int)request.getSession().getAttribute("user_id");
//		//user.setEmail(email);
//		user.setUserId(userid);
		
		int c = 0;
//		try {
//			
//			c = userService.updateEmail(user);
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
		return c;
	}
	
	/**
	 * 
	 * @Title: UserController
	 * @Description: 更新操作用户邮箱信息
	 * @param: @param user
	 * @param: @return
	 * @return: User
	 * @throws
	 */
	@ResponseBody
	@RequestMapping(value = "/updateEmail", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
	@ApiOperation(value="更新操作用户邮箱信息", notes="更新操作用户邮箱信息(post方式)")
	@ApiImplicitParam(name = "maptemp", value = "使用此格式：{}", required = true, dataType = "Map")
	public int updateEmail (@RequestBody Map<String,Object> maptemp) {
		
		User user = new User();


		user.setEmail(maptemp.get("email").toString());

		user.setUserId(Integer.valueOf(maptemp.get("userId").toString()));
		
		int c = 0;
		try {
			
			c = userService.updateEmail(user);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return c;
	}

	/**
	 * 根据Userid获取该用户的信息，并返回
	 * @param maptemp
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "/getUserInfoWithUserId", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
	@ApiOperation(value="根据Userid获取该用户的信息，并返回", notes="根据Userid获取该用户的信息，并返回(post方式)")
	@ApiImplicitParam(name = "maptemp", value = "使用此格式：{}", required = true, dataType = "Map")
	public Map<String,Object> getUserInfoWithUserId (@RequestBody Map<String,Object> maptemp) {

		String userid = (String) maptemp.get("userId");
		User user = new User();
//		user.setUserId(Integer.valueOf(userid));
		try {
			user = userService.findUserInfo(user);
			maptemp.put("userinfo",user);
			maptemp.put("info","s");
		} catch (Exception e) {
			maptemp.put("tip",e.getMessage());
			maptemp.put("info","e");
		}
		return maptemp;
	}

	/**
	 * 
	 * @Title: UserController
	 * @Description: 获取操作用户信息
	 * @param: @param user
	 * @param: @return
	 * @return: User
	 * @throws
	 */
	@RequestMapping(value = "/getUserInfo", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
	@ApiOperation(value="获取操作用户信息及用户标签", notes="获取操作用户信息及用户标签(GET方式)")
	public Map<String,Object> getUserInfo () {

		User user = new User();
		Map<String,Object> map = new HashedMap();
//		log.info((int)em.getCache("shiroCache").get("user_id"));
		try {
			log.info(SecurityUtils.getSubject().getPrincipals().asList());
		}catch(NullPointerException e){
			log.info("No User Be Found!");
			return map;
		}


		Set<?> s = SecurityUtils.getSubject().getPrincipals().asSet();
		Object[] obj = new Object[2];
		int obji = 0;
		Iterator<?> it = s.iterator();
		while(it.hasNext()){
			obj[obji] = it.next();
			log.info(obj.getClass());
			log.info(obj.toString());
			obji++;
		}
		Map<String,String> map1 = (Map<String, String>) obj[1];
		user.setUserName(SecurityUtils.getSubject().getPrincipal().toString());
		user.setUserId(Integer.valueOf(map1.get("userId")));
//		log.info("令牌："+SecurityUtils.getSubject().getPrincipal());
//		log.info("令牌s："+SecurityUtils.getSubject().getPrincipals().asSet());
		//user.setPassword("123123");

		try {

			user = userService.findUserInfo(user);

			List<UserAttention> userAttentionList =userAttentionService.queryAttentionOfUser(user.getUserId());

			String tags = "";
			for (int i =0 ;i<userAttentionList.size();i++){
				if (i==userAttentionList.size()-1){
					tags = tags + userAttentionList.get(i).getCategoryName();
				}else{
					tags = tags + userAttentionList.get(i).getCategoryName()+",";
				}

			}

			map.put("user",user);
			map.put("usertags",tags);

		} catch (Exception e) {
			//e.printStackTrace();
			log.info("error");
		}
		log.info("查询成功..."+user.toString());
		return map;
	}






	/**
	 * 
	 * @Title: UserController
	 * @Description: 更新用户信息
	 * @return: User
	 * @throws
	 */
	@ResponseBody
	@RequestMapping(value = "/updateUserInfo", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
	@ApiOperation(value="更新用户信息", notes="更新用户信息(post方式)")
	@ApiImplicitParam(name = "maptemp", value = "使用此格式：{}", required = true, dataType = "Map")
	public int updateUserInfo (@RequestBody Map<String,Object> maptemp) {
		log.info(maptemp);
		log.info("令牌："+SecurityUtils.getSubject().getPrincipal());
		log.info("令牌s："+SecurityUtils.getSubject().getPrincipals().asSet());
		//Map<String,Object> map = new HashedMap();
		try {
			log.info(SecurityUtils.getSubject().getPrincipals().asList());
		}catch(NullPointerException e){
			log.info("No User Be Found!");

		}
		Set<?> s = SecurityUtils.getSubject().getPrincipals().asSet();
		Object[] obj = new Object[2];
		int obji = 0;
		Iterator<?> it = s.iterator();
		while(it.hasNext()){
			obj[obji] = it.next();
			log.info(obj.getClass());
			log.info(obj.toString());
			obji++;
		}
		Map<String,String> map1 = (Map<String, String>) obj[1];
//		user.setUserName(SecurityUtils.getSubject().getPrincipal().toString());
//		user.setUserId(Integer.valueOf(map1.get("userId")));
		User user = new User();

		user.setUserId(Integer.valueOf(map1.get("userId").toString()));
		user.setNickName(maptemp.get("nickName").toString());
		user.setCity(maptemp.get("city").toString());
		user.setConstellation(maptemp.get("constellation").toString());
		user.setUserMark(maptemp.get("userMark").toString());
		user.setSex(Integer.valueOf(maptemp.get("sex").toString()));
		int c = 0;
		
		try {
			
			c = userService.updateUserInfo(user);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		//System.out.println("查询成功..."+user.getUserMark());
		return c;
	}
	
	/**
	 * 
	 * @Title: UserController
	 * @Description: 检查注册用户信息
	 * @param: @param user
	 * @param: @return
	 * @return: Integer
	 * @throws
	 */
	@ApiOperation(value="检查注册用户信息", notes="检查注册用户信息(get方式，已过时)")
	@RequestMapping(value = "/QueryUsernameIsUnique", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
	public Integer QueryUsernameIsUnique (HttpServletRequest request) {
		int c = 0;
		try {
			log.info("======================"+request.getParameter("userName"));
			c = userService.QueryUsernameIsUnique(request.getParameter("userName"));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return c;
	}
	
	/**
	 * 
	 * @Title: UserController
	 * @Description: 注册用户
	 * @param: @param user
	 * @param: @return
	 * @return: Integer
	 * @throws
	 */
	@RequestMapping(value = "/insertUser", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
	@ApiOperation(value="注册用户", notes="注册用户(get方式，已过时)")
	public Integer insertUser (HttpServletRequest request) {
		int c = 0;
		User user = new User();
		//user.setEmail(request.getParameter("email"));
		user.setEmail("gxl@callbell.cn");
		user.setUserName(request.getParameter("userName"));
		user.setPassword(request.getParameter("password"));
		Date d = new Date();
		user.setCreateTime(new Timestamp(d.getTime()));
		user = entryptPassword(user);
		try {
//			System.out.println("======================"+request.getParameter("userName"));
			c = userService.insertUser(user);
			log.info("添加成功数:"+c);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return c;
	}

	
	public static final int HASH_INTERATIONS = 264544;
    private static final int SALT_SIZE = 32;
	
	 /**
     * 加密密码
     */
    public static void main(String[] args){
    	
    	UserController uc = new UserController();
    	//uc.entryptPassword();
//    	String s = null;
//    	try {
//			s = new String(hex2Bytes("07DDF0E803CFB27598AD5B8F7E7382705C226AB50DAB250D966F2FDC3799475B"), "UTF-8");
//		} catch (UnsupportedEncodingException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//    	System.out.println(s);
    }
    
    /** 
     * byte数组转hex字符串<br/> 
     * 一个byte转为2个hex字符 
     * @param src 
     * @return 
     */  
    public static String bytes2Hex(byte[] src){         
        char[] res = new char[src.length*2];    
        final char hexDigits[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};    
        for(int i=0,j=0; i<src.length; i++){    
            res[j++] = hexDigits[src[i] >>>4 & 0x0f];    
            res[j++] = hexDigits[src[i] & 0x0f];    
        }    
            
        return new String(res);    
    }   
    /**
     * hex字符串转byte数组<br/> 
     * 2个hex转为一个byte 
     * @param src 
     * @return 
     */  
    public static byte[] hex2Bytes(String src){  
        byte[] res = new byte[src.length()/2];        
        char[] chs = src.toCharArray();  
        for(int i=0,c=0; i<chs.length; i+=2,c++){  
            res[c] = (byte) (Integer.parseInt(new String(chs,i,2), 16));  
        }  
          
        return res;  
    }  
    
    public boolean isNotBlank(String plainPassword){
    	
    	if(plainPassword.length() == 0){return false;}
    	
    	if(plainPassword.isEmpty()){return false;}
    	
//    	int i = plainPassword.replace(" ","");
//    	if(i > 0)return false;
    	   // System.out.println("有空格");
    	
    	if(plainPassword.contains(" "))return false;
    	
    	return true;
    	
    }
    public User entryptPassword(User user) {
    	
        String plainPassword = user.getPassword();
        
        if (isNotBlank(plainPassword)) {
            //生成盐
            byte[] salt = Digests.generateSalt(SALT_SIZE);
            //将盐转成字符保存
            user.setSalt(bytes2Hex(salt));
            //System.out.println(bytes2Hex(salt));//Encodes.encodeHex(salt);
            //使用盐来加密密码
            user.setPassword(entryptPassword(plainPassword, salt));
            //System.out.println(entryptPassword(plainPassword, salt));
        }
        
        return user;
    }

    private String entryptPassword(String plainPassword, byte[] salt) {
        //使用shiro 的hash方式
        Sha512Hash sha = new Sha512Hash(plainPassword, salt, HASH_INTERATIONS);
        return sha.toHex();
    }
}
